﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TileManager : MonoBehaviour
{
    public static void HideAllTileOverlay()
    {
        foreach (TileMonoBehaviour tile in AllTilesGenerator())
        {
            tile.unDisplay();
        }
    }

    public void DisplayAllTileOverlayByStatus()
    {
        Debug.Log("DisplayAllTileOverlayByStatus");
        DisplayAllTileOverlay(Color.clear);
    }

    public static void ShowSelectableTiles()
    {
        foreach (TileMonoBehaviour tile in AllTilesGenerator())
        {
            tile.unDisplay();
        
            if (tile.isSelectable)
            {
                tile.SetTileColor(Color.green);
                tile.Display();
            }
        }
    }

    public static void ShowAttackRange(GameObject origin, float detectDistant, AttackRangeType attackRangeType, string layerName)
    {
        HideAllTileOverlay();
        
        Collider2D[] hits = GetRangeCollider2Ds(origin.transform.position, detectDistant, attackRangeType, layerName);

        foreach (var hit in hits)
        {
            try
            {
                TileMonoBehaviour t = hit.GetComponent<TileMonoBehaviour>();
                t.SetTileColor(Color.magenta);
                t.Display();
            }
            catch (Exception e)
            {
                continue;
            }
            
        }
    }

    public static Collider2D[] GetRangeCollider2Ds(Vector3 origin, float detectDistant, AttackRangeType attackRangeType, string layerName)
    {
        Collider2D[] hits;
        switch (attackRangeType)
        {
            case AttackRangeType.Circle:
                float detectLength = Mathf.Sqrt(Mathf.Pow(detectDistant - .1f, 2) * 2);
                
                hits = Physics2D.OverlapBoxAll(
                    origin, 
                    new Vector2(detectLength, detectLength), 
                    45f);
                break;
            case AttackRangeType.Line:
                hits = Physics2D.OverlapAreaAll(origin,
                    origin, ~0, 0f, detectDistant);
                break;
            case AttackRangeType.Sector:
                hits = new Collider2D[0];
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(attackRangeType), attackRangeType, null);
        }

        return hits;
    }
    
    public static void ShowMoveTiles()
    {
        foreach (TileMonoBehaviour tile in AllTilesGenerator())
        {
            tile.unDisplay();
        
            if (tile.isSetPath)
            {
                tile.SetTileColor(Color.green);
                tile.Display();
            }
        }
    }
    
    public static void DisplayAllTileOverlay(Color color)
    {
        foreach (TileMonoBehaviour tile in AllTilesGenerator())
        {
            if (color == Color.clear)
            {
                tile.SetTileColorByStatus();
            }
            else
            {
                tile.SetTileColor(color);
            }
            tile.Display();
        }
    }

    private static IEnumerable<TileMonoBehaviour> AllTilesGenerator()
    {
        var tiles = GameObject.FindGameObjectsWithTag(StaticDataManager.TILE_TAG);
        
        foreach (var tile in tiles)
        {
            yield return tile.GetComponent<TileMonoBehaviour>();
        }
    }

    public static void ResetAllTileScore()
    {
        var tiles = GameObject.FindGameObjectsWithTag(StaticDataManager.TILE_TAG);
        
        foreach (var tile in tiles)
        {
            tile.GetComponent<TileMonoBehaviour>().ResetScore();
        }
    }
}
